package config

import (
	"github.com/DangoXJ/secbinarycheck-result-analyzer/binscope"
	"io/ioutil"
	"os"

	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/DangoXJ/secbinarycheck-result-analyzer/logger"
	"go.uber.org/zap"
	"gopkg.in/yaml.v2"
)

var log *zap.Logger

// BinScopeAnalysisBaseline 编译选项分析基线
var BinScopeAnalysisBaseline map[string]map[string]string

func init() {
	log = logger.GetLogger("CONF")
}

// InitBinScopeAnalysisBaseline 初始化编译选项历史分析结果基线
func InitBinScopeAnalysisBaseline(filename string) {

	log.Info("初始化编译选项基线结果。")

	BinScopeAnalysisBaseline = make(map[string]map[string]string)

	f, err := excelize.OpenFile(filename)
	if err != nil {
		log.Error("初始化编译选项基线结果失败", zap.String("filename", filename))
	}

	if f == nil {
		log.Fatal("未能读取到任何BinScope的分析结果，程序直接停止。")
	} else {
		rows, _ := f.GetRows("Detail")
		for i, row := range rows {
			if i == 0 || len(row) == 0 {
				continue
			}

			key := row[0]

			BinScopeAnalysisBaseline[key] = map[string]string{
				"BIND_NOW":         row[binscope.HeadersAfterIndexMap[binscope.HeaderBindNowAfter]],
				"NX":               row[binscope.HeadersAfterIndexMap[binscope.HeaderNXAfter]],
				"PIC":              row[binscope.HeadersAfterIndexMap[binscope.HeaderPICAfter]],
				"PIE":              row[binscope.HeadersAfterIndexMap[binscope.HeaderPIEAfter]],
				"RELRO":            row[binscope.HeadersAfterIndexMap[binscope.HeaderRELROAfter]],
				"SP":               row[binscope.HeadersAfterIndexMap[binscope.HeaderSPAfter]],
				"NO Rpath/RunPath": row[binscope.HeadersAfterIndexMap[binscope.HeaderRpathAfter]],
				"FS":               row[binscope.HeadersAfterIndexMap[binscope.HeaderFSAfter]],
				"Ftrapv":           row[binscope.HeadersAfterIndexMap[binscope.HeaderFtrapvAfter]],
				"Strip":            row[binscope.HeadersAfterIndexMap[binscope.HeaderStripAfter]],
			}
		}
	}

	if len(BinScopeAnalysisBaseline) == 0 {
		log.Fatal("未能读取到任何BinScope的分析结果，程序直接停止。")
	}
	log.Info("初始化成功。")
}

// logger-path: logs/logger.logger
// binscope:
//   baseline-path: conf/编译选项分析基线.xlsx
//   input-path: test

type conf struct {
	LogPath  string `yaml:"logger-path"`
	BinScope struct {
		BaselinePath string `yaml:"baseline-path"`
		InputPath    string `yaml:"input-path"`
	}
}

// Conf 保存的配置文件
var Conf = conf{}

// InitConf 初始化配置文件
func InitConf(filename string) {
	log.Info("初始化配置文件", zap.String("ConfPath", filename))
	f, err := os.Open(filename)
	if err != nil {
		log.Fatal(err.Error())
	}

	b, _ := ioutil.ReadAll(f)

	err = yaml.Unmarshal(b, &Conf)
	if err != nil {
		log.Fatal(err.Error())
	}
	//log.Info("%+v", Conf)

}
